﻿#include <boost/asio.hpp>
#include <iostream>
#include <cstdio>
boost::asio::awaitable<void> Echo(boost::asio::ip::tcp::socket sock) {
	char arr[1024];
	try {
		while (1) {
			size_t n = co_await sock.async_read_some(boost::asio::buffer(arr, 1024), boost::asio::use_awaitable);
			std::cout << "recieve message is " << std::string(arr, n) << std::endl;
			co_await boost::asio::async_write(sock, boost::asio::buffer(arr, n), boost::asio::use_awaitable);
		}
	}catch (boost::system::error_code& e) {
		std::cout << "echo failed Error value is " << e.value() << " message is " << e.message() << std::endl;
	}
}

boost::asio::awaitable<void> listener(boost::asio::ip::tcp::acceptor& accept) {
	try {
		while (1) {
			boost::asio::ip::tcp::socket sock = co_await accept.async_accept(boost::asio::use_awaitable);
			boost::asio::co_spawn(accept.get_executor(), Echo(std::move(sock)), boost::asio::detached);
		}
	}catch (boost::system::error_code& e) {
		std::cout << "accept failed Error value is " << e.value() << " message is " << e.message() << std::endl;
	}
}

int main() {
	try {
		boost::asio::io_context ioc;
		boost::asio::ip::tcp::acceptor accept(ioc,{ boost::asio::ip::tcp::v4(), 3333});
		std::cout << "Start receiving client connections..." << std::endl;
		boost::asio::signal_set signal(ioc, SIGINT, SIGTERM);
		signal.async_wait([&ioc](auto, auto) {
			ioc.stop();
			});
		boost::asio::co_spawn(ioc, listener(accept), boost::asio::detached);
		ioc.run();
	}
	catch (boost::system::error_code& e) {
		std::cout << "Error value is " << e.value() << " message is " << e.message() << std::endl;
	}
	return 0;
}